package top.lingkang.finalsession.solon;

import org.noear.solon.core.AppContext;
import org.noear.solon.core.handle.Context;
import org.noear.solon.core.handle.SessionState;
import org.noear.solon.core.handle.SessionStateFactory;
import top.lingkang.finalsession.core.FinalRepository;

/**
 * @author lingkang
 * @create by 2024/5/9 17:22
 */
public class FinalSessionSolonFactory implements SessionStateFactory {
    private FinalSessionFilter filter;

    public FinalSessionSolonFactory(AppContext context) {
        context.subBeansOfType(FinalSessionFilter.class, c -> {
            filter = c;
        });
    }

    @Override
    public int priority() {
        return 1995;
    }

    @Override
    public SessionState create(Context ctx) {
        long current = System.currentTimeMillis();
        // 获取sessionId
        String id = filter.config.getSessionHandler().getSessionId(ctx, filter.config.getSessionName());
        FinalSessionState session = null;
        if (id != null) {
            FinalRepository<FinalSessionState> repository = filter.config.getRepository();
            session = repository.getSession(id);
        }
        if (session == null) { // 生成会话
            return generateSession(ctx);
        } else {
            // 判断预留时间
            if (filter.config.isUpdateAccessTime()) {
                // 判断令牌是否有效
                if (session.getLastAccessedTime() + filter.config.getMaxValidTime() < current) {
                    filter.repository.deleteSession(id);
                    // 说明之前的会话已经到期， 生成会话
                    return generateSession(ctx);
                } else {// 更新访问时间
                    session.updateAccessTime(current);
                }
            } else {
                if (session.getLastAccessedTime() + filter.config.getMaxValidTime() - filter.config.getReserveTime() < current) {
                    filter.repository.deleteSession(id);
                    // 说明之前的会话已经到期， 重新生成会话
                    return generateSession(ctx);
                }
            }
        }

        return session;
    }

    private FinalSessionState generateSession(Context ctx) {
        FinalSessionState session = (FinalSessionState) filter.config.getGenerateSession().generateSession(ctx, filter.config);
        // 对响应添加 cookie或自定义操作
        filter.config.getSessionHandler().setSessionId(ctx, filter.config.getSessionName(), session.sessionId());
        return session;
    }
}
